﻿Imports System.Numerics
Imports System.Runtime.CompilerServices
Imports BigDecimals.Math
Partial Class BigDecimal
  'Private Shared Function ExmNivRem(ByVal x As BigDecimal, ByVal y As BigDecimal, ByRef remain As BigDecimal) As BigDecimal
  '  Dim r As BigInteger = Nothing
  '  Dim m As BigInteger = BigInteger.DivRem(x.Digits, y.Digits, r)
  '  remain = New BigDecimal(r, 0)
  '  Return New BigDecimal(m, CUInt(x.PointShift))
  'End Function


  Protected Friend Shared Function Division(ByVal X As BigDecimal, ByVal Y As BigDecimal) As BigDecimal
    ' Create a copy of x,y 
    Dim CX As BigDecimal = CType(X.Clone, BigDecimal)
    Dim CY As BigDecimal = CType(Y.Clone, BigDecimal)
    ' Check the Delta on the PointShift
    Dim ShiftPointDelta As New BigInteger(CInt(CX.DecimalPoint) - CInt(CY.DecimalPoint))
    If ShiftPointDelta > 0 Then
      CY.Digits = CY.Digits * (New BigInteger(10).Pow(ShiftPointDelta - 1))
      CY.DecimalPoint = CUInt(CY.DecimalPoint + ShiftPointDelta)
    Else
      If ShiftPointDelta < 0 Then
        ShiftPointDelta = BigInteger.Abs(ShiftPointDelta)
        CX.Digits = CX.Digits * (New BigInteger(10).Pow(ShiftPointDelta - 1))
        CX.DecimalPoint = CUInt(CX.DecimalPoint + ShiftPointDelta)
      End If
    End If
    ' Checks to see if the result would be negative.
    Dim MakeNegative As Boolean = False

    If CX.Digits.Sign = -1 Then
      MakeNegative = True
      CX.Digits = BigInteger.Abs(CX.Digits)
    End If
    If Not MakeNegative AndAlso CY.Digits.Sign = -1 Then
      MakeNegative = True
      CY.Digits = BigInteger.Abs(CY.Digits)
    End If
    Dim TPS As Integer = 0
    Dim rX As BigDecimal = Zero
    Dim [Mod] As BigInteger = Nothing
    Dim Res = BigInteger.DivRem(CX.Digits, CY.Digits, [Mod])
    rX.Digits = Res
    TPS = Res.ToString.Length + 1
    If Res = 0 Then TPS = 0
    Res = [Mod]
    While [Mod] <> 0
      Res = New BigInteger([Mod].ToByteArray) * New BigInteger(10)
      Res = BigInteger.DivRem(Res, CY.Digits, [Mod])
      TPS += 1
      rX.Digits = (rX.Digits * New BigInteger(10)) + Res
      If [Mod] = 0 Then Exit While
      If TPS > Internal_Limit Then Exit While
    End While
    rX.DecimalPoint = CUInt(TPS)
    If MakeNegative Then Return -rX
    Return rX
  End Function

End Class
